package com.dbgs.fix1lib;

import android.content.Context;
import android.os.Build;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Enumeration;

import dalvik.system.DexFile;

/**
 * Created by Administrator on 2017/8/28.
 */

public class DexManager {


    private static DexManager mInstance;

    private DexManager() {
    }

    public static DexManager getInstance() {
        if (mInstance == null) {
            mInstance = new DexManager();
        }
        return mInstance;
    }

    public void loadFile(File file,Context context) {
        try {
            DexFile dexFile = DexFile.loadDex(file.getAbsolutePath(), new File(context.getCacheDir(), "opt").getAbsolutePath(), Context.MODE_PRIVATE);
            //下一步  得到class   ----取出修复好的Method
            Enumeration<String> entry= dexFile.entries();
            while (entry.hasMoreElements()) {
                //                拿到全类名
                String className=entry.nextElement();
                //                    Class.forName(className);//
                Class clazz=dexFile.loadClass(className, context.getClassLoader());
                if (clazz != null) {
                    fixClazz(clazz);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void fixClazz(Class realClazz) {
     //   服务器修复好的  realClazz
        Method[] methods=realClazz.getDeclaredMethods();
        if (methods == null){
            return;
        }
        for (Method rightMethod : methods){
            Replace replace = rightMethod.getAnnotation(Replace.class);
            if (replace == null){
                continue;
            }
            String  wrongClazzName= replace.clazz();
            String  wrongMethodName = replace.method();
            try {
                Class wrongClazz = Class.forName(wrongClazzName);
                Method  wrongMethod = wrongClazz.getMethod(wrongMethodName,rightMethod.getParameterTypes() );
                if (Build.VERSION.SDK_INT <= 18) {
                    replace(Build.VERSION.SDK_INT, wrongMethod, rightMethod);
                }else {
                    replaceArt(wrongMethod,rightMethod);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }

        }
    }

    private native void  replace(int  sdk,Method wrongMethod, Method rightMethod) ;
    private native  void replaceArt(Method wrongMethod, Method rightMethod);
}